package com.algorithms.datatypes;

import java.util.ArrayList;
import java.util.List;

import com.algorithms.absdatatypes.Apply;
import com.algorithms.absdatatypes.Apply.TREE_TRAVERSAL;
import com.algorithms.absdatatypes.Policy;
import com.algorithms.absdatatypes.TreeNode;

public class TreeNodeImpl<T>  implements TreeNode<T>
{
	private T data;
	private TreeNode<T> parent =null;
    private List<TreeNode<T>> children =null;
    private boolean visitedFlag=false;
	@Override
	public T getData()
	{
		return data;
	}

	@Override
	public boolean isRoot()
	{
		if(getParent()==null)
			return false;
		return true;
	}

	@Override
	public boolean isLeaf()
	{
		if(getChildren()!=null && getChildren().size()>0)
		 return false;
		return true;
	}

	@Override
	public TreeNode<T> getParent()
	{
		return parent;
	}

	@Override
	public List<TreeNode<T>> getChildren()
	{
		return children;
	}

	@Override
	public void setData(T input)
	{
		data=input;
	}

	@Override
	public void setParent(TreeNode<T> input)
	{
		
		parent=input;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void insertChild(TreeNode<T> item)
	{
		item.setParent(this);
		if(children !=null)
		{
			children.add(item);
		}
		else
		{
			children = new ArrayList<TreeNode<T>>();
			children.add(item);
			
		}
	}

	@Override
	public void insertChildren(List<TreeNode<T>> inputChildren)
	{
		/*
		 * First set the parent of all child
		 */
		for(TreeNode<T> child: inputChildren)
		{
			child.setParent(this);
		}
		if(children !=null)
		{
			
			children.addAll(inputChildren);
		}
		else
		{
			children =inputChildren;
			
		}
		
	}

	@Override
	public boolean isVisited()
	{
		return this.visitedFlag;
	}

	@Override
	public void setVisited(boolean flag)
	{
		this.visitedFlag=flag;
		
	}

	@Override
	public  void apply(Policy policy)
	{
		if(policy!=null)
		{
			policy.execute();
		}
		
	}

	

	
	
   
}
